#include "threadPool.h"
#define DEFAULT_MIN_THREADS 3
#define DEFAULT_MAX_THREADS 5
#define DEFAULT_QUEUE_CAPACITY 8
#define DEFAULT_INCREASE 2
#include<iostream>
#include<cstring>
#include<unistd.h>
/*工作线程函数*/
/*消费者*/
void *workThreadFunc(void *arg)
{
    /*线程分离*/
    pthread_detach(pthread_self());
    ThreadPool *pool=(ThreadPool*)arg;

    while(1)
    {
          /*核心目标：从任务队列取元素*/
          pthread_mutex_lock(&(pool->m_mutex));
          while(pool->m_queueSize==0)
          {
            usleep(10000);
            /*等待条件变量*/
            pthread_cond_wait(&(pool->m_notEmpty),&(pool->m_mutex));
            if((pool->m_exitNum)>0&&(pool->m_aliveThreads>pool->m_minThreads))
            {
                /*存活的线程数减一*/
                (pool->m_aliveThreads)--;
                /*离开的线程数减一*/
                (pool->m_exitNum)--;
                /*解锁*/
                pthread_mutex_unlock(&(pool->m_mutex));
                std::cout<<pthread_self()<<"exit pool"<<std::endl;

                for(int idx=0;idx<pool->m_maxThreads;idx++)
                {
                    if(pool->m_threadIds[idx]==pthread_self())
                    {
                        pool->m_threadIds[idx]=0;
                        break;
                    }
                }
                /*线程退出*/
                pthread_exit(NULL);
            }
            
          }
          /*程序执行到这个地方：说明队列有任务*/
          /*取任务队列的对头*/
          Task_t newTask;
          newTask.function=pool->m_queue[pool->m_queueFront].function;
          newTask.arg=pool->m_queue[pool->m_queueFront].arg;


          /*移动对头位置*/
          pool->m_queueFront=(pool->m_queueFront+1)%pool->m_queueCacity;

          /*任务队列的元素个数减一*/
          pool->m_queueSize--;

          /*解锁*/
          pthread_mutex_unlock(&(pool->m_mutex));

          /*加锁*/
          pthread_mutex_lock(&(pool->m_busyMutex));
          /*忙碌的线程数++*/
          (pool->m_busyThreads)++;
           /*解锁*/
          pthread_mutex_unlock(&(pool->m_busyMutex)); 

           /*执行任务*/
          newTask.function(newTask.arg);

           /*加锁*/
          pthread_mutex_lock(&(pool->m_busyMutex));
           /*忙碌的线程数--*/
          (pool->m_busyThreads)--;
           /*解锁*/
          pthread_mutex_unlock(&(pool->m_busyMutex));
            /*发送信号*/
          pthread_cond_signal(&(pool->m_notFull));
            

    }

}
/*管理者线程函数*/
void *manageThreadFunc(void *arg)
{
    /*线程分离*/
    pthread_detach(pthread_self());

    ThreadPool *pool=(ThreadPool*)arg;
    while(true)
    {
        sleep(1);
        /*加锁*/
        pthread_mutex_lock(&(pool->m_mutex));
        int queueSize=pool->m_queueSize;
        int aliveThreadNums=pool->m_aliveThreads;
        /*解锁*/
        pthread_mutex_unlock(&(pool->m_mutex));
        /*加锁*/
        pthread_mutex_lock(&(pool->m_busyMutex));
        int busyThreadsNum=pool->m_busyThreads;
        /*解锁*/
        pthread_mutex_unlock(&(pool->m_busyMutex));

        //std::cout<<"queueSize: "<<queueSize<<"aliveThreadsNum: "<<aliveThreadNums<<"busyThreadsNums:"<<busyThreadsNum<<std::endl;

        /*什么时候需要开辟新的线程*/
        /*任务队列的任务数>存活的线程数—忙碌的线程数*/

        if(queueSize>(aliveThreadNums-busyThreadsNum)&&(aliveThreadNums<pool->m_maxThreads))
        {
            int addCnt=0;
            int ret=0;
            pthread_mutex_lock(&(pool->m_mutex));
            for(int idx=0;idx<pool->m_maxThreads&&addCnt<DEFAULT_INCREASE&&aliveThreadNums<pool->m_maxThreads;idx++)
            {
                /*探测*/
                if(pool->m_threadIds[idx]==0)
                {
                  ret= pthread_create(&(pool->m_threadIds[idx]),NULL,workThreadFunc,pool);
                  if(ret==-1)
                  {
                    perror("creat error\n");
                    break;

                  }
                  addCnt++;
                  /*存活的线程数++*/
                  pool->m_aliveThreads++;
                }

            }
            pthread_mutex_unlock(&(pool->m_mutex));
        }



        /*什么时候需要减少线程池中线程的数量*/
        /*任务队列的任务数远小于*/
        if((pool->m_queueSize<aliveThreadNums-busyThreadsNum)&&(aliveThreadNums>pool->m_minThreads))
        {
            /*加锁*/
            pthread_mutex_lock(&(pool->m_mutex));
            pool->m_exitNum=DEFAULT_INCREASE;
            for(int idx=0;idx<DEFAULT_INCREASE;idx++)
            {
               pthread_cond_signal(&(pool->m_notEmpty));
            }
            /*解锁*/
            pthread_mutex_unlock(&(pool->m_mutex));
        }
    }
  

}
    
/*构造函数*/
ThreadPool::ThreadPool(int minThread, int maxThread, int maxQueueCapacity)
{
    /*参数校验*/
    if(minThread<0||maxThread<0||maxQueueCapacity<0)
    {
        minThread=DEFAULT_MIN_THREADS;
        maxThread=DEFAULT_MAX_THREADS;
        maxQueueCapacity=DEFAULT_QUEUE_CAPACITY;

    }
    /*维护住属性*/
    m_minThreads=minThread;
    m_maxThreads=maxThread;
    m_queueCacity=maxQueueCapacity;
    m_aliveThreads=0;
    m_busyThreads=0;

    /*创建线程池空间*/
    try
    {
        m_threadIds=new pthread_t[maxThread];
        if(m_threadIds==nullptr)
        {
            perror("new error");
        }
        memset(m_threadIds,0,sizeof(pthread_t)*maxThread);
    }
    catch(const std::exception&e)
    {
        std::cerr<<e.what()<<"\0";
    }
    

    /*创建队列*/
    m_queue=new Task_t[m_queueCacity];
    if(m_queue==nullptr)
    {
        perror("new error");
        exit(-1);
    }
    /*清除脏数据*/
    memset(m_queue,0,sizeof(Task_t)*m_queueCacity);

    /*任务队列的元素个数为0*/
    m_queueSize=0;
    /*任务队列的对头*/
    m_queueFront=0;
    /*任务队列的队尾*/
     m_queueRear=0;
     /*初始化锁*/
     int ret= pthread_mutex_init(&m_mutex,NULL);
     if(ret!=0)
     {
        perror("mutex init error:");
        exit(-1);
     }
         /*初始化忙碌锁*/
     ret= pthread_mutex_init(&m_busyMutex,NULL);
     if(ret!=0)
     {
        perror("mutex init error:");
        exit(-1);
     }

     /*初始化条件变量*/
     ret=pthread_cond_init(&m_notEmpty,NULL);
    if(ret!=0)
     {
        perror("mutex init error:");
        exit(-1);
     }
       /*初始化条件变量*/
     ret=pthread_cond_init(&m_notFull,NULL);
    if(ret!=0)
     {
        perror("mutex init error:");
        exit(-1);
     }

     /*创建最小的线程数*/
     ret=0;
    for(int idx=0;idx<m_minThreads;idx++)
    {
       ret=pthread_create(&m_threadIds[idx],NULL,workThreadFunc,this);
       if(ret==-1)
       {
            perror("thread create error:");
            exit(-1);
       }
          /*每创建一个线程，存活的线程数++*/
            m_aliveThreads++;
    }
 

    /*创建管理者线程*/
    ret=pthread_create(&m_manageId,NULL,manageThreadFunc,this);
    if(ret==-1)
    {
        perror("thread create error:");
        exit(-1);
    }
    /*要删除的线程数量*/
    m_exitNum=0;

 
}
/*添加任务*/
/*生产者*/
void ThreadPool::addTask(void *(function)(void *arg),void *arg)
{
    if(function==nullptr)
    {
        return;
    }
    /*将任务到队添加到对列中*/
    /*加锁*/
    pthread_mutex_lock(&m_mutex);
    /*任务个数达到上限*/
    while(m_queueSize==m_queueCacity)
    { 
        pthread_cond_wait(&m_notFull,&m_mutex);
    }
    /*程序执行到这个地方，说明队列有位置放*/
    m_queue[m_queueRear].function=function;
    m_queue[m_queueRear].arg=arg;
    /*更新队列的尾部*/
    m_queueRear=(m_queueRear+1)%m_queueCacity;
    m_queueSize++;

    /*解锁*/
    pthread_mutex_unlock(&m_mutex);
    /*发信号*/
    pthread_cond_signal(&m_notEmpty);

}
